﻿#pragma once

#include "is_valid.h"

#include <chrono>
#include <iostream>

namespace CAGD
{

/**
 * @brief 高精度计时器.
 *
 */
typedef std::chrono::high_resolution_clock __clock;
typedef std::chrono::milliseconds __milliseconds;

#define TIMER_START(NAME) auto __TIMER##NAME##_START = __clock::now();
#define TIMER_END(NAME)                                                                                                \
    __clock::time_point __TIMER##NAME##_END = __clock::now();                                                          \
    {                                                                                                                  \
        auto d = std::chrono::duration_cast<__milliseconds>(__TIMER##NAME##_END - __TIMER##NAME##_START).count();      \
        std::cout << "Timer " << #NAME << ": " << (d / 1000.0) << "s\n";                                               \
    }

#define TIMER_QT_END(NAME)                                                                                             \
    __clock::time_point __TIMER##NAME##_END = __clock::now();                                                          \
    {                                                                                                                  \
        auto d = std::chrono::duration_cast<__milliseconds>(__TIMER##NAME##_END - __TIMER##NAME##_START).count();      \
        qDebug() << "Timer " << #NAME << ": " << (d / 1000.0) << "s";                                                  \
    }

/**
 * @brief 检查是否具有对应的成员函数.
 *
 */
inline auto hasDebugTime = is_valid([](auto &&x) -> decltype(x.DebugTime()) {});

/**
 * @brief 匹配具有 DebugTime 成员的类.
 * @return
 * @param obj
 * @see
 */
template <class T>
inline auto debug_time(T &obj) -> typename std::enable_if<decltype(hasDebugTime(obj))::value, std::string>::type
{
    return obj.DebugTime();
}

} // namespace CAGD
